package com.withoutwords.engine;

import java.io.Serializable;

import java.util.ArrayList;
import java.util.Arrays;

import java.util.List;

import org.json.JSONException;
import org.json.JSONObject;

import com.withoutwords.R;

public class Round implements ConvertableJson, Serializable {

	String roundId = "";
	int roundNo;

	boolean[] wordsState;
	RoundMediaType mediaType;
	String mediaName = "";
	RoundMediaTime mediaTime;
	int currentWordIndex;
	Guess lastApprovedGuess;
	String[] words;

	volatile ArrayList<Guess> unreadGuesses;

	public Guess getLastApprovedGuess() {
		return lastApprovedGuess;
	}

	public void setLastApprovedGuess(Guess lastApprovedGuess) {
		this.lastApprovedGuess = lastApprovedGuess;
	}

	public ArrayList<Guess> getUnreadGuesses() {
		return unreadGuesses;
	}

	public void addUnreadGuess(Guess guess) {
		if (unreadGuesses == null) {
			unreadGuesses = new ArrayList<Guess>();
		}
		unreadGuesses.add(guess);
	}
	public void removeUnreadGuess(Guess guess) {
		if (unreadGuesses != null ) {
			unreadGuesses.remove(guess);
		}
		
	}

	public void clearUnreadGuesses() {
		if (unreadGuesses != null) {
			unreadGuesses.clear();
		}
	}

	public int getCurrentWordIndex() {
		return currentWordIndex;
	}

	public void setCurrentWordIndex(int currentWordIndex) {
		this.currentWordIndex = currentWordIndex;
	}

	public int getRoundNo() {
		return roundNo;
	}

	public void setRoundNo(int roundNo) {
		this.roundNo = roundNo;
	}

	public String getRoundId() {
		return roundId;
	}

	public String[] getWords() {
		return words;
	}

	public boolean[] getWordsState() {
		return wordsState;
	}

	public RoundMediaType getMediaType() {
		return mediaType;
	}

	public void setMediaType(RoundMediaType mediaType) {
		this.mediaType = mediaType;
	}

	public String getMediaName() {
		return mediaName;
	}

	public void setMediaName(String mediaName) {
		this.mediaName = mediaName;

		words = mediaName.split(" ");
		wordsState = new boolean[words.length];
		Arrays.fill(wordsState, false);
	}

	public void approveGuess(Guess guess) {
		if (guess != null) {
			lastApprovedGuess = guess;
			int index = guess.wordIndex;
			if (index == -1) {
				Arrays.fill(wordsState, true);
			}
			if (index >= 0 && index < wordsState.length)
				wordsState[index] = true;
		}
	}

	public boolean isRoundSolved() {
		if (wordsState != null) {
			boolean solved = wordsState[0];
			for (int i = 1; i < wordsState.length; i++) {
				solved &= wordsState[i];
			}
			return solved;
		} else
			return false;
	}

	public RoundMediaTime getMediaTime() {
		return mediaTime;
	}

	public void setMediaTime(RoundMediaTime mediaTime) {
		this.mediaTime = mediaTime;
	}

	@Override
	public JSONObject toJSON() {
		JSONObject obj = new JSONObject();
		try {
			obj.put("roundId", roundId);
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		try {
			obj.put(Common.roundNoCode, roundId);
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		try {
			obj.put("currentWordIndex", currentWordIndex);
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		try {
			if (mediaType != null) {
				obj.put("mediaType", mediaType.ordinal());
			}
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		try {
			if (mediaTime != null) {
				obj.put("mediaTime", mediaTime.ordinal());
			}
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		try {
			obj.put("mediaName", mediaName);
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		try {
			String solved = "";
			for (int i = 0; i < wordsState.length; i++) {
				if (wordsState[i]) {
					solved += i + "_";
				}
			}
			// to remove the last underscore
			if(solved.length() > 2)
			{
			solved = solved.substring(0, solved.length() - 2);
			}
			obj.put("solved", solved);

		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return obj;
	}

	@Override
	public boolean fromJSON(JSONObject obj) {
		try {
			roundId = obj.getString("roundId");
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		try {
			roundNo = obj.getInt(Common.roundNoCode);
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		try {
			currentWordIndex = obj.getInt("currentWordIndex");
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		try {
			setMediaName(obj.getString("mediaName"));
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		try {
			mediaTime = RoundMediaTime.values()[obj.getInt("mediaTime")];
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		try {
			mediaType = RoundMediaType.values()[obj.getInt("mediaType")];
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		try {
			String solved = obj.getString("solved");
			String[] solvedIndices = solved.split("_");

			for (int i = 0; i < solvedIndices.length; i++) {
				try {
					int ind = new Integer(solvedIndices[i]);
					wordsState[ind] = true;
				} catch (NumberFormatException e) {
					// TODO: handle exception
				}
			}
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return true;

	}

	@Override
	public boolean equals(Object o) {
		Round r = (Round) o;

		return this.roundId.equals(r.roundId);
	}

	public int getMediaInfoResource() {
		int resID = R.drawable.series_old;
		if (mediaType == RoundMediaType.Series
				&& mediaTime == RoundMediaTime.Old)
			resID = R.drawable.series_old;
		else if (mediaType == RoundMediaType.Series
				&& mediaTime == RoundMediaTime.New)
			resID = R.drawable.series_new;
		else if (mediaType == RoundMediaType.Series
				&& mediaTime == RoundMediaTime.Recent)
			resID = R.drawable.series_current;
		else if (mediaType == RoundMediaType.Play
				&& mediaTime == RoundMediaTime.Old)
			resID = R.drawable.play_old;
		else if (mediaType == RoundMediaType.Play
				&& mediaTime == RoundMediaTime.Recent)
			resID = R.drawable.play_current;
		else if (mediaType == RoundMediaType.Play
				&& mediaTime == RoundMediaTime.New)
			resID = R.drawable.play_new;
		else if (mediaType == RoundMediaType.Song
				&& mediaTime == RoundMediaTime.Old)
			resID = R.drawable.song_old;
		else if (mediaType == RoundMediaType.Song
				&& mediaTime == RoundMediaTime.Recent)
			resID = R.drawable.song_current;
		else if (mediaType == RoundMediaType.Song
				&& mediaTime == RoundMediaTime.New)
			resID = R.drawable.song_new;
		else if (mediaType == RoundMediaType.Film
				&& mediaTime == RoundMediaTime.Old)
			resID = R.drawable.film_old;
		else if (mediaType == RoundMediaType.Film
				&& mediaTime == RoundMediaTime.Recent)
			resID = R.drawable.film_current;
		else if (mediaType == RoundMediaType.Film
				&& mediaTime == RoundMediaTime.New)
			resID = R.drawable.film_new;

		return resID;
	}

}
